package cz.cvut.fit.mi_paa.bucket;

import cz.cvut.fit.mi_paa.abs.Instance;
import cz.cvut.fit.mi_paa.bucket.strategy.BucketScoreGenerator;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * Created with IntelliJ IDEA.
 * User: milos
 * Date: 19.10.12
 * Time: 2:13
 * To change this template use File | Settings | File Templates.
 */
public class BucketInstance extends Instance {
    private int id;
    private Bucket[] buckets;
    private int numBuckets;
    private int[] endConfiguration;
    private BucketScoreGenerator scoreGenerator;
    private List<Operation> operations;


    public BucketInstance(int id,int numBuckets, Bucket[] buckets, int[] endConfiguration,List<Operation> operations) {
        this.numBuckets = numBuckets;
        this.id = id;
        this.buckets = buckets;
        this.endConfiguration = endConfiguration;
        this.operations = new ArrayList<Operation>(operations);
    }

    public int getNumBuckets() {
        return numBuckets;
    }

    public int getId() {
        return id;
    }

    public Bucket[] getBuckets() {
        return buckets;
    }

    public boolean isSolution() {
        for (int i = 0; i < numBuckets; i++) {
             if (!buckets[i].equalsVolume(endConfiguration[i])) return false;
        }
        return true;
    }

    public boolean empty(int i) {
        return buckets[i].empty();
    }

    public boolean fill(int i) {
        return buckets[i].fill();
    }

    public String writeBuckets() {
        StringBuilder builder = new StringBuilder();
        for (Bucket bucket : buckets) {
            builder.append("[" + bucket.getCapacity()+ "," + bucket.getVolume() + "], ");
        }
        return builder.toString();
    }

    @Override
    public BucketInstance clone() throws CloneNotSupportedException {
        Bucket[] bucketsCopy = new Bucket[numBuckets];
        for (int i=0;i<numBuckets;i++) {
            bucketsCopy[i] = buckets[i].clone();
        }
        BucketInstance copy = new BucketInstance(id,numBuckets,bucketsCopy,endConfiguration,this.operations);
        copy.setScoreGenerator(this.scoreGenerator);
        return copy;
    }

    public int[] getEndConfiguration() {
        return endConfiguration;
    }

    public void nextOperation(Operation operation) {
        operations.add(operation);
    }

    public List<Operation> getOperations() {
        return operations;
    }

    @Override
    public String toString() {
        return "id: "+ id + ", size: "+ numBuckets + ", " + writeBuckets();
    }

    @Override
    public int hashCode() {
        return Arrays.hashCode(buckets);
    }

    public double getScore() {
        return scoreGenerator.getScore(this);
    }

    public void setScoreGenerator(BucketScoreGenerator scoreGenerator) {
        this.scoreGenerator = scoreGenerator;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        BucketInstance that = (BucketInstance) o;

        if (id != that.id) return false;
        if (numBuckets != that.numBuckets) return false;
        if (!Arrays.equals(buckets, that.buckets)) return false;
        if (!Arrays.equals(endConfiguration, that.endConfiguration)) return false;

        return true;
    }
}
